/**
 * 网络状态管理模块
 * 处理网络状态变化、离线检测和数据同步
 */
class NetworkManager {
    constructor() {
        this.isOnline = navigator.onLine;
        this.wasOffline = false;
        this.listeners = [];
        this.syncQueue = [];
        this.retryCount = 0;
        this.maxRetries = 3;
        this.retryDelay = 2000; // 2秒
        this.logger = window.logger ? window.logger.createContextLogger('NetworkManager') : console;
        
        this._init();
    }
    
    /**
     * 初始化网络管理器
     * @private
     */
    _init() {
        // 监听网络状态变化
        window.addEventListener('online', this._handleOnline.bind(this));
        window.addEventListener('offline', this._handleOffline.bind(this));
        
        // 初始状态检查
        this._checkNetworkStatus();
        
        this.logger.info('网络管理器已初始化', { isOnline: this.isOnline });
    }
    
    /**
     * 检查网络状态
     * @private
     */
    async _checkNetworkStatus() {
        try {
            // 尝试连接到API服务器
            const response = await fetch(`${window.envConfig ? window.envConfig.getApiBaseUrl() : 'http://localhost:3000'}/health`, {
                method: 'GET',
                cache: 'no-cache',
                timeout: 5000
            });
            
            const wasOffline = !this.isOnline;
            this.isOnline = response.ok;
            
            if (wasOffline && this.isOnline) {
                this._handleOnline();
            } else if (!wasOffline && !this.isOnline) {
                this._handleOffline();
            }
        } catch (error) {
            if (this.isOnline) {
                this.isOnline = false;
                this._handleOffline();
            }
        }
    }
    
    /**
     * 处理网络连接恢复
     * @private
     */
    _handleOnline() {
        if (!this.isOnline || this.wasOffline) {
            this.isOnline = true;
            this.wasOffline = false;
            this.retryCount = 0;
            
            this.logger.info('网络连接已恢复');
            
            // 通知所有监听器
            this._notifyListeners('online', { isOnline: true });
            
            // 处理同步队列
            this._processSyncQueue();
            
            // 显示通知
            this._showNotification('网络连接已恢复', 'success');
        }
    }
    
    /**
     * 处理网络连接断开
     * @private
     */
    _handleOffline() {
        if (this.isOnline || !this.wasOffline) {
            this.isOnline = false;
            this.wasOffline = true;
            
            this.logger.warn('网络连接已断开');
            
            // 通知所有监听器
            this._notifyListeners('offline', { isOnline: false });
            
            // 显示通知
            this._showNotification('网络连接已断开，数据将在恢复后同步', 'warning');
        }
    }
    
    /**
     * 通知所有监听器
     * @private
     * @param {string} event - 事件类型
     * @param {Object} data - 事件数据
     */
    _notifyListeners(event, data) {
        this.listeners.forEach(listener => {
            try {
                listener(event, data);
            } catch (error) {
                this.logger.error('监听器执行失败:', error);
            }
        });
    }
    
    /**
     * 处理同步队列
     * @private
     */
    async _processSyncQueue() {
        if (this.syncQueue.length === 0) {
            return;
        }
        
        this.logger.info(`开始处理同步队列，共 ${this.syncQueue.length} 项任务`);
        
        // 复制队列并清空原队列
        const queue = [...this.syncQueue];
        this.syncQueue = [];
        
        // 处理队列中的每个任务
        for (const task of queue) {
            try {
                await this._executeSyncTask(task);
                this.logger.debug('同步任务执行成功:', task.type);
            } catch (error) {
                this.logger.error('同步任务执行失败:', error);
                
                // 如果失败，重新加入队列
                this.syncQueue.push(task);
                
                // 如果重试次数过多，停止处理
                if (this.retryCount >= this.maxRetries) {
                    this.logger.error('同步重试次数过多，停止处理');
                    this._showNotification('数据同步失败，请检查网络连接', 'error');
                    break;
                }
            }
        }
        
        // 如果队列中还有任务，延迟后重试
        if (this.syncQueue.length > 0) {
            this.retryCount++;
            this.logger.info(`${this.retryDelay}ms 后进行第 ${this.retryCount} 次重试`);
            
            setTimeout(() => {
                this._processSyncQueue();
            }, this.retryDelay * this.retryCount);
        } else {
            this.retryCount = 0;
            this.logger.info('所有同步任务已完成');
            this._showNotification('数据同步完成', 'success');
        }
    }
    
    /**
     * 执行同步任务
     * @private
     * @param {Object} task - 同步任务
     */
    async _executeSyncTask(task) {
        const { type, data, endpoint } = task;
        
        switch (type) {
            case 'POST':
                return await this._postRequest(endpoint, data);
            case 'PUT':
                return await this._putRequest(endpoint, data);
            case 'DELETE':
                return await this._deleteRequest(endpoint, data);
            default:
                throw new Error(`未知的同步任务类型: ${type}`);
        }
    }
    
    /**
     * 发送POST请求
     * @private
     * @param {string} endpoint - API端点
     * @param {Object} data - 请求数据
     */
    async _postRequest(endpoint, data) {
        const response = await fetch(`${window.envConfig ? window.envConfig.getApiBaseUrl() : 'http://localhost:3000'}${endpoint}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        });
        
        if (!response.ok) {
            throw new Error(`POST请求失败: ${response.status}`);
        }
        
        return await response.json();
    }
    
    /**
     * 发送PUT请求
     * @private
     * @param {string} endpoint - API端点
     * @param {Object} data - 请求数据
     */
    async _putRequest(endpoint, data) {
        const response = await fetch(`${window.envConfig ? window.envConfig.getApiBaseUrl() : 'http://localhost:3000'}${endpoint}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        });
        
        if (!response.ok) {
            throw new Error(`PUT请求失败: ${response.status}`);
        }
        
        return await response.json();
    }
    
    /**
     * 发送DELETE请求
     * @private
     * @param {string} endpoint - API端点
     * @param {Object} data - 请求数据
     */
    async _deleteRequest(endpoint, data) {
        const response = await fetch(`${window.envConfig ? window.envConfig.getApiBaseUrl() : 'http://localhost:3000'}${endpoint}`, {
            method: 'DELETE',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        });
        
        if (!response.ok) {
            throw new Error(`DELETE请求失败: ${response.status}`);
        }
        
        return await response.json();
    }
    
    /**
     * 显示通知
     * @private
     * @param {string} message - 通知消息
     * @param {string} type - 通知类型
     */
    _showNotification(message, type) {
        // 如果有全局通知函数，使用它
        if (typeof window.showNotification === 'function') {
            window.showNotification(message, type);
        } else {
            // 否则使用简单的控制台输出
            this.logger.info(`通知: ${message} (${type})`);
        }
    }
    
    /**
     * 添加网络状态监听器
     * @param {Function} listener - 监听器函数
     */
    addListener(listener) {
        if (typeof listener === 'function') {
            this.listeners.push(listener);
        }
    }
    
    /**
     * 移除网络状态监听器
     * @param {Function} listener - 监听器函数
     */
    removeListener(listener) {
        const index = this.listeners.indexOf(listener);
        if (index !== -1) {
            this.listeners.splice(index, 1);
        }
    }
    
    /**
     * 添加同步任务到队列
     * @param {Object} task - 同步任务
     */
    addSyncTask(task) {
        this.syncQueue.push(task);
        this.logger.debug('已添加同步任务到队列:', task.type);
        
        // 如果当前在线，立即处理队列
        if (this.isOnline) {
            this._processSyncQueue();
        }
    }
    
    /**
     * 获取当前网络状态
     * @returns {Object} 网络状态信息
     */
    getStatus() {
        return {
            isOnline: this.isOnline,
            wasOffline: this.wasOffline,
            queueLength: this.syncQueue.length,
            retryCount: this.retryCount
        };
    }
    
    /**
     * 手动触发网络状态检查
     */
    async checkNetworkStatus() {
        await this._checkNetworkStatus();
        return this.getStatus();
    }
    
    /**
     * 添加离线操作到队列
     * @param {string} type - 操作类型 (create, update, delete)
     * @param {string} dataType - 数据类型 (tasks, notes, settings)
     * @param {string} id - 数据ID（可选，对于创建操作可能为空）
     * @param {Object} data - 操作数据
     * @returns {Promise<void>}
     */
    async addOfflineOperation(type, dataType, id, data) {
        const logger = this.logger.createContextLogger('OfflineOperation');
        
        try {
            // 获取现有队列
            const queue = this._getOfflineOperationQueue();
            
            // 添加新操作
            const operation = {
                id: this._generateOperationId(),
                type,
                dataType,
                id: id || null,
                data,
                timestamp: new Date().toISOString(),
                retryCount: 0
            };
            
            queue.push(operation);
            
            // 保存队列
            this._saveOfflineOperationQueue(queue);
            
            logger.debug(`离线操作已添加到队列: ${type} ${dataType} ${id || ''}`);
            
            // 标记数据已变更
            this._markDataChanged(dataType);
        } catch (error) {
            logger.error('添加离线操作失败:', error);
            throw error;
        }
    }
    
    /**
     * 获取离线操作队列
     * @private
     * @returns {Array} 操作队列
     */
    _getOfflineOperationQueue() {
        try {
            const queue = localStorage.getItem('offlineOperationQueue');
            return queue ? JSON.parse(queue) : [];
        } catch (error) {
            this.logger.error('获取离线操作队列失败:', error);
            return [];
        }
    }
    
    /**
     * 保存离线操作队列
     * @private
     * @param {Array} queue - 操作队列
     */
    _saveOfflineOperationQueue(queue) {
        try {
            localStorage.setItem('offlineOperationQueue', JSON.stringify(queue));
        } catch (error) {
            this.logger.error('保存离线操作队列失败:', error);
            throw error;
        }
    }
    
    /**
     * 生成操作ID
     * @private
     * @returns {string} 操作ID
     */
    _generateOperationId() {
        return 'op_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
    }
    
    /**
     * 标记数据已变更
     * @private
     * @param {string} dataType - 数据类型
     */
    _markDataChanged(dataType) {
        try {
            const key = `${dataType}ChangedSinceLastSync`;
            localStorage.setItem(key, 'true');
        } catch (error) {
            this.logger.error(`标记${dataType}数据变更失败:`, error);
        }
    }
    
    /**
     * 检查是否有待同步的数据
     * @returns {Promise<boolean>} 是否有待同步数据
     */
    async hasPendingSyncData() {
        try {
            // 检查离线操作队列
            const queue = this._getOfflineOperationQueue();
            if (queue.length > 0) {
                return true;
            }
            
            // 检查数据变更标记
            const tasksChanged = localStorage.getItem('tasksChangedSinceLastSync') === 'true';
            const notesChanged = localStorage.getItem('notesChangedSinceLastSync') === 'true';
            const settingsChanged = localStorage.getItem('settingsChangedSinceLastSync') === 'true';
            
            return tasksChanged || notesChanged || settingsChanged;
        } catch (error) {
            this.logger.error('检查待同步数据失败:', error);
            return true; // 出错时默认认为有待同步数据
        }
    }
    
    /**
     * 清除离线操作队列
     * @param {string} dataType - 可选，指定数据类型，只清除该类型的操作
     */
    clearOfflineOperationQueue(dataType = null) {
        try {
            if (dataType) {
                // 只清除指定数据类型的操作
                const queue = this._getOfflineOperationQueue();
                const filteredQueue = queue.filter(op => op.dataType !== dataType);
                this._saveOfflineOperationQueue(filteredQueue);
                this.logger.info(`已清除${dataType}类型的离线操作`);
            } else {
                // 清除所有操作
                localStorage.removeItem('offlineOperationQueue');
                this.logger.info('已清除所有离线操作');
            }
        } catch (error) {
            this.logger.error('清除离线操作队列失败:', error);
        }
    }
    
    /**
     * 获取离线操作统计
     * @returns {Object} 操作统计
     */
    getOfflineOperationStats() {
        try {
            const queue = this._getOfflineOperationQueue();
            const stats = {
                total: queue.length,
                byType: {
                    create: 0,
                    update: 0,
                    delete: 0
                },
                byDataType: {
                    tasks: 0,
                    notes: 0,
                    settings: 0
                },
                failedRetries: 0
            };
            
            for (const operation of queue) {
                // 按操作类型统计
                if (stats.byType[operation.type] !== undefined) {
                    stats.byType[operation.type]++;
                }
                
                // 按数据类型统计
                if (stats.byDataType[operation.dataType] !== undefined) {
                    stats.byDataType[operation.dataType]++;
                }
                
                // 统计失败重试次数
                if (operation.retryCount > 0) {
                    stats.failedRetries += operation.retryCount;
                }
            }
            
            return stats;
        } catch (error) {
            this.logger.error('获取离线操作统计失败:', error);
            return {
                total: 0,
                byType: { create: 0, update: 0, delete: 0 },
                byDataType: { tasks: 0, notes: 0, settings: 0 },
                failedRetries: 0
            };
        }
    }
    
    /**
     * 获取网络状态信息
     * @returns {Object} 网络状态信息
     */
    getNetworkStatusInfo() {
        return {
            isOnline: this.isOnline,
            wasOffline: this.wasOffline,
            queueLength: this.syncQueue.length,
            retryCount: this.retryCount,
            pendingSyncData: this.hasPendingSyncData(),
            offlineOperationStats: this.getOfflineOperationStats()
        };
    }
    
    /**
     * 设置网络状态变更回调
     * @param {Function} callback - 回调函数
     */
    onNetworkStatusChange(callback) {
        if (typeof callback === 'function') {
            this.listeners.push(callback);
        }
    }
    
    /**
     * 移除网络状态变更回调
     * @param {Function} callback - 要移除的回调函数
     */
    offNetworkStatusChange(callback) {
        const index = this.listeners.indexOf(callback);
        if (index !== -1) {
            this.listeners.splice(index, 1);
        }
    }
    
    /**
     * 销毁网络管理器
     */
    destroy() {
        // 移除事件监听器
        if (typeof window !== 'undefined') {
            window.removeEventListener('online', this._handleOnline.bind(this));
            window.removeEventListener('offline', this._handleOffline.bind(this));
        }
        
        // 清空监听器
        this.listeners = [];
        
        this.logger.info('网络管理器已销毁');
    }
}

// 创建全局网络管理器实例
const networkManager = new NetworkManager();

// 导出网络管理器
if (typeof module !== 'undefined' && module.exports) {
    module.exports = { networkManager, NetworkManager };
} else {
    window.networkManager = networkManager;
    window.NetworkManager = NetworkManager;
}